package com.thero.core.net;

import com.thero.core.chess.Message;

import java.util.Arrays;

/**
 * Created by wusk on 2017/11/28.
 * 自定义流式消息协议，符合协议的消息
 */
public class ProtocolMessage {
    /**
     * 数据包数据段最大长度
     */
    public static final int MAX_PACKAGE_LENGTH = 2000;

    private MessageHeader header;
    private byte[] message;

    public MessageHeader getHeader() {
        return header;
    }

    public void setHeader(MessageHeader header) {
        this.header = header;
    }

    public byte[] getMessage() {
        return message;
    }

    public void setMessage(byte[] message) {
        this.message = message;
    }

    public static ProtocolMessage[] newMessage(Message message){
        short cmd = message.getCmd();
        byte[] bytes = message.getInformation();
        return newMessage(cmd, bytes);
    }

    /**
     * 组装数据包的方法
     * @param cmd 命令字
     * @param data 数据
     * @return 数据包数组
     */
    public static ProtocolMessage[] newMessage(short cmd, byte[] data){
        int length = data.length;
        int count = length / MAX_PACKAGE_LENGTH + 1; //计算包数量
        int index = 0;
        ProtocolMessage[] result = new ProtocolMessage[count];

        while(index < count){
            int size = 0;
            if(count > 1){
                size = MAX_PACKAGE_LENGTH;
            }else {
                size = length % MAX_PACKAGE_LENGTH;
            }
            int from = index * size;
            int to = from + size;
            byte[] bytes = Arrays.copyOfRange(data, from, to);

            MessageHeader h = new MessageHeader();
            h.setLength(MessageHeader.HEADER_SIZE + size);
            h.setCount((short)count);
            h.setIndex((short)index);
            h.setCommand(cmd);
            ProtocolMessage pm = new ProtocolMessage();
            pm.setHeader(h);
            pm.setMessage(bytes);
            result[index] = pm;

            index = index + 1;
        }
        return result;
    }

    public static byte[] readBytes(int res) {
        byte[] targets = new byte[4];

        targets[0] = (byte) (res & 0xff);// 最低位
        targets[1] = (byte) ((res >> 8) & 0xff);// 次低位
        targets[2] = (byte) ((res >> 16) & 0xff);// 次高位
        targets[3] = (byte) (res >>> 24);// 最高位,无符号右移。
        return targets;
    }

    public static byte[] readBytes(short in){
        int temp = in;
        byte[] b = new byte[2];
        for (int i = 0; i < b.length; i++) {
            b[i] = new Integer(temp & 0xff).byteValue();//将最低位保存在最低位
            temp = temp >> 8; // 向右移8位
        }
        return b;
    }

    public static void writeInt(byte[] bytes, int in, int index){
        byte[] ibytes = readBytes(in);
        bytes[index] = ibytes[0];
        bytes[index + 1] = ibytes[1];
        bytes[index + 2] = ibytes[2];
        bytes[index + 3] = ibytes[3];
    }

    public static void writeShort(byte[] bytes, short in, int index){
        byte[] ibytes = readBytes(in);
        bytes[index] = ibytes[0];
        bytes[index + 1] = ibytes[1];
    }
}
